/**
 * Company : SIANGKLOM.
 * Created By : Chatree Siangklom
 * Created On : Oct 11, 2013  2:17:40 PM 
 * e-Mail : dr_chatree@hotmail.com
 * Mobile Phone : (+66) 087-921-5115
 * Package Name : com.tis.interfaces.controller.fi.outbound
 * File Name : CreditNoteController.java
 * TODO
 */
package com.tis.interfaces.controller.fi.outbound;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import promis.utility.CommonService;
import sap.business.commons.SapMessageReturn;
import sap.business.enumeration.Module;
import sap.business.enumeration.STAGING_STATUS;
import sap.business.fi.outbound.CreditNoteInterServices;

import com.tis.database.entitys.promis.GlPostingDetail;
import com.tis.database.entitys.promis.VwSyncGlPostingDetail;
import com.tis.database.entitys.security.AdUserLogin;
import com.tis.database.entitys.staging.ApplicationLoging;
import com.tis.database.entitys.staging.FiCreditNoteOutb;
import com.tis.database.entitys.staging.XmlResultback;
import com.tis.database.services.promis.ICustomerCreditNoteServices;
import com.tis.database.services.promis.IGlPostingDetailServices;
import com.tis.database.services.promis.IVwSyncGlPostingDetailServices;
import com.tis.database.services.staging.IFiCreditNoteOutbServices;
import com.tis.interfaces.controller.commons.CommonController;

/**
 * @author Chatree Siangklom of Administrator
 * Date =Oct 11, 2013 : 2:17:40 PM 
 * CreateBy=Chatree Siangklom
 * TODO
 */
@Controller
@RequestMapping(value=CreditNoteController.url)
public class CreditNoteController extends CommonController {
	
	private static final Logger logging = LoggerFactory.getLogger(CreditNoteController.class);	
	public static final String  url = "/fi/outbound/rental/creditnote";
	public static final String  uri = "/fi/outbound";
	
	@Autowired
	private IFiCreditNoteOutbServices iFiCreditNoteOutbServices;
	
	@RequestMapping(value="index")
	public String Index(HttpServletRequest request, Model model) throws Exception {
		logging.info(url + "/index {Index}");
		setCurrentAppsInstanceNo();
		KeepLogs(new ApplicationLoging(getCurrentAppsInstanceNo(), "W", "WELCOME", null, getCurrentAppsInstanceNo()));
		
		try {
			//Put History 		
			try { UserAccessTime(request, this.toString()); }catch(Exception e) {e.printStackTrace();}
			
			if(!UserLoginValidation((request)))
				return "redirect:/login";
			
			CreditNoteForm form = new CreditNoteForm();
			form.setSyncCreatedOnStart(CommonService.ConvertDateToString(new Date()));
			form.setSyncCreatedOnEnd(CommonService.ConvertDateToString(new Date()));
			form.setMaxResult("5000");
			
			logging.info("form =" + form.toString());
			model.addAttribute("ObjectForm", form);
			
		} catch (Exception e) {
			e.printStackTrace();
			logging.error(e.getMessage());
			KeepLogs(new ApplicationLoging(getCurrentAppsInstanceNo(), "E", CommonService.CutString(e.getMessage(), 2900), null, getCurrentAppsInstanceNo()));
			throw e;
		}
		
		return uri + "/creditnote";
	}
	
	@RequestMapping(value="search", method = RequestMethod.POST)
	public String Search(HttpServletRequest request, Model model, @ModelAttribute("ObjectForm") @Valid	CreditNoteForm form, BindingResult result) throws Exception {
		try {
			logging.info(url + "/search {search}");
			setCurrentAppsInstanceNo();
			KeepLogs(new ApplicationLoging(getCurrentAppsInstanceNo(), "W", "WELCOME", null, getCurrentAppsInstanceNo()));
			
			//Put History 		
			try { UserAccessTime(request, this.toString()); }catch(Exception e) {e.printStackTrace();}
			
			if(!UserLoginValidation((request)))
				throw new Exception("Can't Search, Please Login first !!!!");
			
		} catch (Exception e) {
			e.printStackTrace();
			logging.error(e.getMessage());
			KeepLogs(new ApplicationLoging(getCurrentAppsInstanceNo(), "E", CommonService.CutString(e.getMessage(), 2900), null, getCurrentAppsInstanceNo()));
			throw e;
		}
		
		return uri + "/creditnote";
	}

	@RequestMapping(value="search/json", method = RequestMethod.GET, headers="accept=application/json")
	@ResponseBody
	public List<FiCreditNoteOutb> Search(
											@RequestParam(value="stagingId", required=false) String stagingId,
											@RequestParam(value="sapstagingId", required=false) String sapstagingId,
											@RequestParam(value="company", required=false) String company,
											@RequestParam(value="project", required=false) String project,
											@RequestParam(value="documentNo", required=false) String documentNo,
											@RequestParam(value="refDocNo", required=false) String refDocNo,
											@RequestParam(value="accountCode", required=false) String accountCode,
											@RequestParam(value="accountCode2", required=false) String accountCode2,
											@RequestParam(value="unitNo", required=false) String unitNo,
											@RequestParam(value="status", required=false) String status,																
											@RequestParam(value="instanceNo", required=false) String instanceNo,
											@RequestParam(value="syncCreatedOnStart", required=false) String syncCreatedOnStart,
											@RequestParam(value="syncCreatedOnEnd", required=false) String syncCreatedOnEnd,
											@RequestParam(value="maxResult", required=true) String maxResult,
											HttpServletRequest request, 
											HttpServletResponse response) throws Exception {
		
		logging.info(url + "search/json {Search} ::: method = RequestMethod.GET");
		setCurrentAppsInstanceNo();
		KeepLogs(new ApplicationLoging(getCurrentAppsInstanceNo(), "W", "WELCOME", null, getCurrentAppsInstanceNo()));
		
		if(!UserLoginValidation((request))) {
			response.setStatus(500);
			return null;
		}
		
		try {
			
			if(!UserLoginValidation((request)))
				throw new Exception("Can't Search, Please Login first !!!!");
			
			logging.info("stagingId --> " +  stagingId); 
			logging.info("sapstagingId --> " +  sapstagingId); 
			logging.info("company --> " +  company);
			logging.info("project --> " +  project);
			logging.info("documentNo --> " +  documentNo);
			logging.info("refDocNo --> " +  refDocNo);
			logging.info("accountCode --> " +  accountCode);
			logging.info("accountCode2 --> " + accountCode2);
			logging.info("unitNo --> " +  unitNo);
			logging.info("status --> " +  status);
			logging.info("syncCreatedOnStart --> " +  syncCreatedOnStart);
			logging.info("syncCreatedOnEnd --> " +  syncCreatedOnEnd);
			logging.info("maxResult --> " +  maxResult);
			
			if(CommonService.IsNull(syncCreatedOnStart))
				syncCreatedOnStart = "1980-01-01";
			
			if(CommonService.IsNull(syncCreatedOnEnd))
				syncCreatedOnStart = "2017-12-31";

			int maxResultInt = -1;
			if(!CommonService.IsNull(maxResult))
				maxResultInt = (Integer.parseInt(CommonService.IsNullRZero(maxResult)) == 0) ? -1 : Integer.parseInt(CommonService.IsNullRZero(maxResult));
					
			List<FiCreditNoteOutb> lst = iFiCreditNoteOutbServices.Search(stagingId, sapstagingId, company, project, documentNo, refDocNo, accountCode, accountCode2, unitNo, status, instanceNo, "", syncCreatedOnStart, syncCreatedOnEnd, maxResultInt);
			
			logging.info("FiCreditNoteOutb Size = " + CommonService.getSize(lst));
			
			if(CommonService.getSize(lst) > 0){
				for(FiCreditNoteOutb value : lst)
					logging.info(value.toString());
			}
			
			if(CommonService.getSize(lst) > 0) 
				return lst;
			
		} catch (Exception e) {
			e.printStackTrace();
			logging.error(e.getMessage());
			KeepLogs(new ApplicationLoging(getCurrentAppsInstanceNo(), "E", CommonService.CutString(e.getMessage(), 2900), null, getCurrentAppsInstanceNo()));
			throw e;
		}
		
		return null;
	}
	
	@Autowired IVwSyncGlPostingDetailServices iVwSyncGlPostingDetailServices;
	@Autowired IGlPostingDetailServices iGlPostingDetailServices;
	
	@Autowired ICustomerCreditNoteServices iCustomerCreditNoteServices;
	
	//INVOICES  - Invoice, Debit Note                   
	//PMS_PAYMENTS_RECEIVED - Receive
	//CUSTOMER_CREDIT_NOTES - Credit Note
	//PAYMENT_VOUCHERS - Deposit Return
	//interfacekey=84MlQYjqHe1sT3D5oP6q1xwKOoJ5fsaR85MXOGJUn4OCnw8YcnQK0u6C02ar59jrkC5{||5||}QLusNTuoXnOKqIbYU{||9||}QeSzufWivdcezXOKUJ9Bnnf9c086p5J4sjsSZwDDYFn0OiEA{||9||}Ga6qa39w{||9||}ZRWh9g{||4||}{||4||}	
	FiCreditNoteOutb thisInstanceOf = new FiCreditNoteOutb();
	
	@RequestMapping(value="interface", method = RequestMethod.GET)
	public HttpEntity<byte[]> Interface(
								@RequestParam(value="company", required=true) String company,
								@RequestParam(value="project", required=true) String project,
								@RequestParam(value="documentNo", required=true) String documentNo,
								@RequestParam(value="interfacekey", required=true) String interfacekey,
								@RequestParam(value="processAction", required=false, defaultValue="") String processAction,
								Model model,
								HttpServletRequest request, 
								HttpServletResponse response) {
		
		logging.info(url + "/interface {interface}");
		logging.info("company = " + company + "//projecy = " + project + "//documentNo = " + documentNo + "//processAction=" + processAction);
		setCurrentAppsInstanceNo();
		XmlResultback xmlResultback = null;
		
		try {
			xmlResultback = new XmlResultback(Module.RECEIPT.toString(), getCurrentAppsInstanceNo(), iFiCreditNoteOutbServices.getCurrentDatabaseDate());
			KeepLogs(new ApplicationLoging(getCurrentAppsInstanceNo(), "W", "WELCOME", null, getCurrentAppsInstanceNo()));
			
			//Put History	
			try { UserAccessTime(request, this.toString()); }catch(Exception e) {e.printStackTrace();}
			
			if(CommonService.IsNull(interfacekey)) 
			{
				xmlResultback.setMsgcode(STAGING_STATUS.EE.toString());
				xmlResultback.setMsgDescription("Authentication Key is fail !!!");

				return(ToXml(xmlResultback));
			}
			
			AdUserLogin adUserLoin =  AuthenOfPromis(interfacekey);
			if(adUserLoin != null){			
				//Source Code Writing----------------------------------->
				List<VwSyncGlPostingDetail> lst = iVwSyncGlPostingDetailServices.SearchByDocumentNo(company, project, documentNo, null, null);
				logging.info("VwSyncGlPostingDetail size=" + CommonService.getSize(lst));
				
				//Step 1 Write to Staging
				List<FiCreditNoteOutb> newlst = new ArrayList<FiCreditNoteOutb>();
				if(CommonService.getSize(lst) > 0){
					
					for(VwSyncGlPostingDetail value : lst){
						FiCreditNoteOutb obj = new FiCreditNoteOutb();
						obj.setCompany(value.getCompany());
						obj.setProject(value.getProject());
						obj.setAccountCode(value.getAccountCode());						
						obj.setStatus(value.getStatus());
						obj.setAccountCode2(value.getAccountCode2());
						obj.setAmount(CommonService.IsNullRNull(value.getAmount()));
						obj.setArticleType(value.getArticleType());
						obj.setBa(value.getBa());
						obj.setBaseAmount(CommonService.IsNullRNull(value.getBaseAmount()));
						obj.setBaseLineDate(value.getBaseLineDate());
						obj.setBatchNo(CommonService.IsNullRNull(value.getBatchNo()));
						obj.setBoqItem(value.getBoqItem());
						obj.setBoqSerial(CommonService.IsNullRNull(value.getBoqSerial()));
						obj.setBoqSeries(CommonService.IsNullRNull(value.getBoqSeries()));
						obj.setBoqType(value.getBoqType());
						obj.setBranchCode(CommonService.IsNullRNull(value.getBranchCode()));
						obj.setChargeCode(value.getChargeCode());
						obj.setChargeDescription(value.getChargeDescription());
						obj.setClOb(value.getClOb());
						obj.setCostCenter(value.getCostCenter());
						obj.setCostCode(value.getCostCode());
						obj.setCreatedBy(value.getCreatedBy());
						obj.setCreatedOn(CommonService.ConvertDateToSAPStringDate(value.getCreatedOn()));
						obj.setCurrency(value.getCurrency());
						obj.setDescription1(value.getDescription1());
						obj.setDescription2(null);
						obj.setDocType(value.getDocType());
						obj.setDocumentNo(value.getDocumentNo());
						obj.setDummy1(value.getDummy1());
						obj.setDummy2(value.getDummy2());
						obj.setDummy3(value.getDummy3());
						obj.setDummy4(value.getDummy4());
						obj.setDummy5(value.getDummy5());
						obj.setExpBatchNo(value.getExpBatchNo());
						obj.setExpCreatedOn(CommonService.ConvertDateTimeToString(value.getExpCreatedOn()));
						obj.setExpRefCode(value.getExpRefCode());						
						obj.setFileId(CommonService.IsNullRNull(value.getFileId()));
						obj.setFlagManual(value.getFlagManual());
						obj.setGlPostingSeqNumber(value.getGlPostingSeqNumber());
						obj.setImportInvRef(value.getImportInvRef());
						obj.setNarration(value.getNarration());
						obj.setOrgCode(value.getOrgCode());
						obj.setPoNo(CommonService.IsNullRNull(value.getPoNo()));
						obj.setPoSeqNo(CommonService.IsNullRNull(value.getPoSeqNo()));
						obj.setPoSeries(value.getPoSeries());
						obj.setPoType(value.getPoType());
						obj.setPostingDate(CommonService.IsNullRNull(value.getPostingDate()));
						obj.setPostingKey(value.getPostingKey());
						obj.setPostingNumber(CommonService.IsNullRNull(value.getPostingNumber()));
						obj.setPostingSeries(value.getPostingSeries());
						obj.setRefDocNo(value.getRefDocNo());
						obj.setRefTenant(value.getRefTenant());
						obj.setReferenceCode(value.getReferenceCode());
						obj.setRevision(CommonService.IsNullRNull(value.getRevision()));
						obj.setSpecialGl(value.getSpecialGl());
						obj.setSubProject(value.getSubProject());
						
						obj.setSyncCreatedby(adUserLoin.getUserLogin());
						obj.setSyncCreatedon(new Date());
						obj.setSyncIssync("N");
						obj.setMsgCode(STAGING_STATUS.SS.toString());
						obj.setMsgDesc("Write to staging success.");
						obj.setSyncUpdatedby(null);
						obj.setSyncUpdatedon(null);
						
						obj.setUnitNo(value.getUnitNo());
						obj.setVatCode(value.getVatCode());
						obj.setVoucherDate(CommonService.ConvertDateToSAPStringDate(value.getVoucherDate()));
						obj.setVoucherNumber(CommonService.IsNullRNull(value.getVoucherNumber()));
						obj.setVoucherSeries(value.getVoucherSeries());
						obj.setVoucherType(value.getVoucherType());
						obj.setCostCtr(null);
						obj.setInternalOrder(null);
						obj.setBankType(null);
						obj.setWbs(null);
						
						obj.setProcessAction(processAction);
						obj.setPmsUseStart(iFiCreditNoteOutbServices.getCurrentDatabaseDate());
												
						obj.setId(CommonService.IsNullRNull(iFiCreditNoteOutbServices.NextSequence()));
						obj.setInstanceNo(getCurrentAppsInstanceNo());
						newlst.add(obj);
											
						logging.info("FiCreditNoteOutb.toString=" + obj.toString());
					}
					
					iFiCreditNoteOutbServices.saveOrUpdate(newlst);
					iFiCreditNoteOutbServices.StampUsedTimePROC(getCurrentAppsInstanceNo(), new Date(), null, thisInstanceOf);
					iFiCreditNoteOutbServices.StampUsedTimePms(getCurrentAppsInstanceNo(), new Date(), new Date(), thisInstanceOf);
					
					xmlResultback.setMsgcode(newlst.get(0).getMsgCode());
					xmlResultback.setMsgDescription("Write to Staging Success.");
					
					//Step 2,3 Write to Staging and Sending to SAP
					iFiCreditNoteOutbServices.StampUsedTimeSend(getCurrentAppsInstanceNo(), new Date(), null, thisInstanceOf);
					List<FiCreditNoteOutb> crediNolist = iFiCreditNoteOutbServices.findByInstanceNo(getCurrentAppsInstanceNo(), thisInstanceOf);
					logging.info("value_lst size =" + CommonService.getSize(crediNolist));
					SapMessageReturn<FiCreditNoteOutb> sapMessageReturn = new CreditNoteInterServices().SynchroToSap(crediNolist);
					iFiCreditNoteOutbServices.StampUsedTimeSend(getCurrentAppsInstanceNo(), null, new Date(), thisInstanceOf);
					
					xmlResultback.setMsgcode((CommonService.getSize(sapMessageReturn.getOutput()) > 0) ? sapMessageReturn.getOutput().get(0).getMsgCode() : null);
					xmlResultback.setMsgDescription((CommonService.getSize(sapMessageReturn.getOutput()) > 0) ? sapMessageReturn.getOutput().get(0).getMsgDesc() : null);
					
					
					//Step 4 Update Message to Staging Table
					List<FiCreditNoteOutb> lstResultBack = iFiCreditNoteOutbServices.UpdateBackSapMessage(sapMessageReturn.getOutput());
					
					//Step 5 Update to GL Table
					List<GlPostingDetail> lstGLResultBack = iGlPostingDetailServices.UpdateBackSapMessageCN(lstResultBack);
					
					//Step 6 Update Back to Promis Table
					iCustomerCreditNoteServices.UpdateBackSapMessage(lstGLResultBack.get(0));
					
					xmlResultback.setMsgcode((CommonService.getSize(lstResultBack) > 0) ? lstResultBack.get(0).getMsgCode() : null);
					xmlResultback.setMsgDescription((CommonService.getSize(lstResultBack) > 0) ? lstResultBack.get(0).getMsgDesc() : null);
					
					iFiCreditNoteOutbServices.StampUsedTimePROC(getCurrentAppsInstanceNo(), null, new Date(), thisInstanceOf);
					
				}else{
					xmlResultback.setMsgcode(STAGING_STATUS.EE.toString());
					xmlResultback.setMsgDescription("Data not found. Criteria=" + "[Company:" + company + "//Projecy:" + project + "//DocumentNo:" + documentNo + "]");
				}
			}else
			{
				xmlResultback.setMsgcode(STAGING_STATUS.EE.toString());
				xmlResultback.setMsgDescription("Authentication is fail !!!");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			logging.error(e.getMessage());
			KeepLogs(new ApplicationLoging(getCurrentAppsInstanceNo(), "E", CommonService.CutString(e.getMessage(), 2900), null, getCurrentAppsInstanceNo()));
			
			xmlResultback.setMsgcode(STAGING_STATUS.EE.toString());
			xmlResultback.setMsgDescription(e.getMessage());
			iFiCreditNoteOutbServices.SaveErrorToStaging(getCurrentAppsInstanceNo(), STAGING_STATUS.EE, e.getMessage());
			
		}finally{
			try {
				iFiCreditNoteOutbServices.StampUsedTimePROC(getCurrentAppsInstanceNo(), null, new Date(), thisInstanceOf);				
			} catch (Exception e) {
				e.printStackTrace();
				logging.error("Exception=" + e.getMessage());
				KeepLogs(new ApplicationLoging(getCurrentAppsInstanceNo(), "E", CommonService.CutString(e.getMessage(), 2900), null, getCurrentAppsInstanceNo()));
				iFiCreditNoteOutbServices.SaveErrorToStaging(getCurrentAppsInstanceNo(), STAGING_STATUS.EE, e.getMessage());
			}
		}
		return(ToXml(xmlResultback));
	}
}
